import gobject
import gtk

if __name__ == '__main__':
    import os, sys
    sys.path.append(os.path.split(__file__)[0])


class Clock(object):
    def __init__(self, **kwargs):
        ms = kwargs.get('interval_ms')
        if not ms:
            ms = kwargs.get('interval_sec', .04) * 1000
        self.interval = int(ms)
        
        callbacks = kwargs.get('callbacks', [])
        self.running = False
        self.timer_id = None
        self.callbacks = set()
        self.callbacks_to_delete = set()
        for cb in callbacks:
            self.add_callback(cb)
        self.ticks = 0
    @property
    def seconds(self):
        return self.ticks * self.interval / 1000.
    @property
    def fps(self):
        return 1.0 / (self.interval / 1000.)
    def start(self):
        self.stop()
        self.ticks = 0
        self.listener = TickListener(self.on_timer)
        self.timer_id = gobject.timeout_add(int(self.interval), self.listener.on_tick, self.listener.id)
        self.running = True
        return self.timer_id
    def stop(self):
        if self.timer_id:
            gobject.source_remove(self.timer_id)
            self.timer_id = None
            self.running = False
            self.ticks = 0
    def add_callback(self, callback):
        self.callbacks.add(callback)
    def del_callback(self, callback):
        self.callbacks_to_delete.add(callback)
    def _do_remove_callbacks(self):
        for cb in self.callbacks_to_delete:
            self.callbacks.discard(cb)
        if len(self.callbacks) == 0:
            self.stop()
        self.callbacks_to_delete.clear()
    def on_timer(self, id):
        if id == self.listener.id:
            self.ticks += 1
            for cb in self.callbacks:
                cb(self)#ticks=self.ticks, seconds=(self.ticks * self.interval) / 1000, clock=self)
            self._do_remove_callbacks()
        return True
class TickListener(object):
    def __init__(self, callback):
        self.id = id(self)
        self.callback = callback
    def on_tick(self, cbid):
        return self.callback(cbid)
        


        


if __name__ == '__main__':
    import math
    def callback(**kwargs):
        print kwargs.get('timeV'), kwargs.get('value')
    def fn_function(timeV):
        return math.sin(timeV)
    def on_tick(**kwargs):
        ms = kwargs.get('ms')
        fn.on_interval(ms)
    def on_click(btn):
        sq.start()
    #cl = Clock()
    fn = Functional(callback=callback, function=fn_function)
    sq = Sequencer(fps=10, duration=1, mode='updn')
    sq.add_controller(fn)
    
    w = gtk.Window()
    w.set_property('default_width', 200)
    w.set_property('default_height', 200)
    btn = gtk.Button()
    btn.connect('clicked', on_click)
    w.add(btn)
    w.show_all()
    
    gtk.main()
